home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freaks Macintosh Archive
/
Freaks Macintosh Archive.bin
/
Freaks Macintosh Archives
/
Hacking & Misc
/
UNIX Cracking
/
MacCracSource.sit
/
MacCrac.source
/
Source
/
crack-lib.c
< prev
next >
Wrap
Text File
|
1995-01-20
|
14KB
|
751 lines
/*
* This program is copyright Alec Muffett 1991 except for some portions of
* code in "crack-fcrypt.c" which are copyright Robert Baldwin, Icarus Sparry
* and Alec Muffett. The author(s) disclaims all responsibility or liability
* with respect to it's usage or its effect upon hardware or computer
* systems, and maintain copyright as set out in the "LICENCE" document which
* accompanies distributions of Crack v4.0 and upwards.
*/
#include "crack.h"
#include <string.h>
#include <strings.h>
#define RULE_NOOP ':'
#define RULE_PREPEND '^'
#define RULE_APPEND '$'
#define RULE_REVERSE 'r'
#define RULE_UPPERCASE 'u'
#define RULE_LOWERCASE 'l'
#define RULE_PLURALISE 'p'
#define RULE_CAPITALISE 'c'
#define RULE_DUPLICATE 'd'
#define RULE_REFLECT 'f'
#define RULE_SUBSTITUTE 's'
#define RULE_MATCH '/'
#define RULE_NOT '!'
#define RULE_LT '<'
#define RULE_GT '>'
#define RULE_EXTRACT 'x'
#define RULE_OVERSTRIKE 'o'
#define RULE_INSERT 'i'
#define RULE_EQUALS '='
#define RULE_PURGE '@'
#define RULE_CLASS '?' /* class rule? socialist ethic in cracker? */
extern void Log();
void
Trim (string) /* remove trailing whitespace from a string */
register char *string;
{
register char *ptr;
for (ptr = string; *ptr; ptr++);
while ((--ptr >= string) && isspace (*ptr));
*(++ptr) = '\0';
}
char *
Clone (string)
char *string;
{
register char *retval;
retval = (char *) malloc (strlen (string) + 1);
if (retval)
{
strcpy (retval, string);
}
return (retval);
}
int
Suffix (word, suffix)
char *word;
char *suffix;
{
register int i;
register int j;
i = strlen (word);
j = strlen (suffix);
if (i > j)
{
return (STRCMP ((word + i - j), suffix));
} else
{
return (-1);
}
}
char *
Reverse (str) /* return a pointer to a reversal */
register char *str;
{
register int i;
register int j;
static char area[STRINGSIZE];
j = i = strlen (str);
while (*str)
{
area[--i] = *str++;
}
area[j] = '\0';
return (area);
}
char *
Uppercase (str) /* return a pointer to an uppercase */
register char *str;
{
register char *ptr;
static char area[STRINGSIZE];
ptr = area;
while (*str)
{
*(ptr++) = CRACK_TOUPPER (*str);
str++;
}
*ptr = '\0';
return (area);
}
char *
Lowercase (str) /* return a pointer to an lowercase */
register char *str;
{
register char *ptr;
static char area[STRINGSIZE];
ptr = area;
while (*str)
{
*(ptr++) = CRACK_TOLOWER (*str);
str++;
}
*ptr = '\0';
return (area);
}
char *
Capitalise (str) /* return a pointer to an capitalised */
register char *str;
{
register char *ptr;
static char area[STRINGSIZE];
ptr = area;
while (*str)
{
*(ptr++) = CRACK_TOLOWER (*str);
str++;
}
*ptr = '\0';
area[0] = CRACK_TOUPPER (area[0]);
return (area);
}
char *
Pluralise (string) /* returns a pointer to a plural */
register char *string;
{
register int length;
static char area[STRINGSIZE];
length = strlen (string);
strcpy (area, string);
if (!Suffix (string, "ch") ||
!Suffix (string, "ex") ||
!Suffix (string, "ix") ||
!Suffix (string, "sh") ||
!Suffix (string, "ss"))
{
/* bench -> benches */
strcat (area, "es");
} else if (length > 2 && string[length - 1] == 'y')
{
if (strchr ("aeiou", string[length - 2]))
{
/* alloy -> alloys */
strcat (area, "s");
} else
{
/* gully -> gullies */
strcpy (area + length - 1, "ies");
}
} else if (string[length - 1] == 's')
{
/* bias -> biases */
strcat (area, "es");
} else
{
/* catchall */
strcat (area, "s");
}
return (area);
}
char *
Substitute (string, old, gnew) /* returns pointer to a swapped about copy */
register char *string;
register char old;
register char gnew;
{
register char *ptr;
static char area[STRINGSIZE];
ptr = area;
while (*string)
{
*(ptr++) = (*string == old ? gnew : *string);
string++;
}
*ptr = '\0';
return (area);
}
char *
Purge (string, target) /* returns pointer to a purged copy */
register char *string;
register char target;
{
register char *ptr;
static char area[STRINGSIZE];
ptr = area;
while (*string)
{
if (*string != target)
{
*(ptr++) = *string;
}
string++;
}
*ptr = '\0';
return (area);
}
/* -------- CHARACTER CLASSES START HERE -------- */
/*
* this function takes two inputs, a class identifier and a character, and
* returns non-null if the given character is a member of the class, based
* upon restrictions set out below
*/
int
MatchClass (class, input)
register char class;
register char input;
{
register char c;
register int retval;
retval = 0;
switch (class)
{
/* ESCAPE */
case '?': /* ?? -> ? */
if (input == '?')
{
retval = 1;
}
break;
/* ILLOGICAL GROUPINGS (ie: not in ctype.h) */
case 'V':
case 'v': /* vowels */
c = CRACK_TOLOWER (input);
if (strchr ("aeiou", c))
{
retval = 1;
}
break;
case 'C':
case 'c': /* consonants */
c = CRACK_TOLOWER (input);
if (strchr ("bcdfghjklmnpqrstvwxyz", c))
{
retval = 1;
}
break;
case 'W':
case 'w': /* whitespace */
if (strchr ("\t ", input))
{
retval = 1;
}
break;
case 'P':
case 'p': /* punctuation */
if (strchr (".`,:;'!?\"", input))
{
retval = 1;
}
break;
case 'S':
case 's': /* symbols */
if (strchr ("$%%^&*()-_+=|\\[]{}#@/~", input))
{
retval = 1;
}
break;
/* LOGICAL GROUPINGS */
case 'L':
case 'l': /* lowercase */
if (islower (input))
{
retval = 1;
}
break;
case 'U':
case 'u': /* uppercase */
if (isupper (input))
{
retval = 1;
}
break;
case 'A':
case 'a': /* alphabetic */
if (isalpha (input))
{
retval = 1;
}
break;
case 'X':
case 'x': /* alphanumeric */
if (isalnum (input))
{
retval = 1;
}
break;
case 'D':
case 'd': /* digits */
if (isdigit (input))
{
retval = 1;
}
break;
default:
Log ("MatchClass: unknown class %c\n", class);
return (0);
break;
}
if (isupper (class))
{
return (!retval);
}
return (retval);
}
char *
PolyStrchr (string, class)
register char *string;
register char class;
{
while (*string)
{
if (MatchClass (class, *string))
{
return (string);
}
string++;
}
return ((char *) 0);
}
char *
PolySubst (string, class, new) /* returns pointer to a swapped about copy */
register char *string;
register char class;
register char new;
{
register char *ptr;
static char area[STRINGSIZE];
ptr = area;
while (*string)
{
*(ptr++) = (MatchClass (class, *string) ? new : *string);
string++;
}
*ptr = '\0';
return (area);
}
char *
PolyPurge (string, class) /* returns pointer to a purged copy */
register char *string;
register char class;
{
register char *ptr;
static char area[STRINGSIZE];
ptr = area;
while (*string)
{
if (!MatchClass (class, *string))
{
*(ptr++) = *string;
}
string++;
}
*ptr = '\0';
return (area);
}
/* -------- BACK TO NORMALITY -------- */
int
Char2Int (character)
char character;
{
if (isdigit (character))
{
return (character - '0');
} else if (islower (character))
{
return (character - 'a' + 10);
} else if (isupper (character))
{
return (character - 'A' + 10);
}
return (-1);
}
char *
Mangle (input, control) /* returns a pointer to a controlled Mangle */
char *input;
char *control;
{
int limit;
register char *ptr;
static char area[STRINGSIZE];
char area2[STRINGSIZE];
area[0] = '\0';
strcpy (area, input);
for (ptr = control; *ptr; ptr++)
{
switch (*ptr)
{
case RULE_NOOP:
break;
case RULE_REVERSE:
strcpy (area, Reverse (area));
break;
case RULE_UPPERCASE:
strcpy (area, Uppercase (area));
break;
case RULE_LOWERCASE:
strcpy (area, Lowercase (area));
break;
case RULE_CAPITALISE:
strcpy (area, Capitalise (area));
break;
case RULE_PLURALISE:
strcpy (area, Pluralise (area));
break;
case RULE_REFLECT:
strcat (area, Reverse (area));
break;
case RULE_DUPLICATE:
strcpy (area2, area);
strcat (area, area2);
break;
case RULE_GT:
if (!ptr[1])
{
Log ("Mangle: '>' missing argument in '%s'\n", control);
return ((char *) 0);
} else
{
limit = Char2Int (*(++ptr));
if (limit < 0)
{
Log ("Mangle: '>' weird argument in '%s'\n", control);
return ((char *) 0);
}
if (strlen (area) <= limit)
{
return ((char *) 0);
}
}
break;
case RULE_LT:
if (!ptr[1])
{
Log ("Mangle: '<' missing argument in '%s'\n", control);
return ((char *) 0);
} else
{
limit = Char2Int (*(++ptr));
if (limit < 0)
{
Log ("Mangle: '<' weird argument in '%s'\n", control);
return ((char *) 0);
}
if (strlen (area) >= limit)
{
return ((char *) 0);
}
}
break;
case RULE_PREPEND:
if (!ptr[1])
{
Log ("Mangle: prepend missing argument in '%s'\n", control);
return ((char *) 0);
} else
{
area2[0] = *(++ptr);
strcpy (area2 + 1, area);
strcpy (area, area2);
}
break;
case RULE_APPEND:
if (!ptr[1])
{
Log ("Mangle: append missing argument in '%s'\n", control);
return ((char *) 0);
} else
{
register char *string;
string = area;
while (*(string++));
string[-1] = *(++ptr);
*string = '\0';
}
break;
case RULE_EXTRACT:
if (!ptr[1] || !ptr[2])
{
Log ("Mangle: extract missing argument in '%s'\n", control);
return ((char *) 0);
} else
{
register int i;
int start;
int length;
start = Char2Int (*(++ptr));
length = Char2Int (*(++ptr));
if (start < 0 || length < 0)
{
Log ("Mangle: extract: weird argument in '%s'\n", control);
return ((char *) 0);
}
strcpy (area2, area);
for (i = 0; length-- && area2[start + i]; i++)
{
area[i] = area2[start + i];
}
/* cant use strncpy() - no trailing NUL */
area[i] = '\0';
}
break;
case RULE_OVERSTRIKE:
if (!ptr[1] || !ptr[2])
{
Log ("Mangle: overstrike missing argument in '%s'\n", control);
return ((char *) 0);
} else
{
register int i;
i = Char2Int (*(++ptr));
if (i < 0)
{
Log ("Mangle: overstrike weird argument in '%s'\n",
control);
return ((char *) 0);
} else
{
++ptr;
if (area[i])
{
area[i] = *ptr;
}
}
}
break;
case RULE_INSERT:
if (!ptr[1] || !ptr[2])
{
Log ("Mangle: insert missing argument in '%s'\n", control);
return ((char *) 0);
} else
{
register int i;
register char *p1;
register char *p2;
i = Char2Int (*(++ptr));
if (i < 0)
{
Log ("Mangle: insert weird argument in '%s'\n",
control);
return ((char *) 0);
}
p1 = area;
p2 = area2;
while (i && *p1)
{
i--;
*(p2++) = *(p1++);
}
*(p2++) = *(++ptr);
strcpy (p2, p1);
strcpy (area, area2);
}
break;
/* THE FOLLOWING RULES REQUIRE CLASS MATCHING */
case RULE_PURGE: /* @x or @?c */
if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
{
Log ("Mangle: delete missing arguments in '%s'\n", control);
return ((char *) 0);
} else if (ptr[1] != RULE_CLASS)
{
strcpy (area, Purge (area, *(++ptr)));
} else
{
strcpy (area, PolyPurge (area, ptr[2]));
ptr += 2;
}
break;
case RULE_SUBSTITUTE: /* sxy || s?cy */
if (!ptr[1] || !ptr[2] || (ptr[1] == RULE_CLASS && !ptr[3]))
{
Log ("Mangle: subst missing argument in '%s'\n", control);
return ((char *) 0);
} else if (ptr[1] != RULE_CLASS)
{
strcpy (area, Substitute (area, ptr[1], ptr[2]));
ptr += 2;
} else
{
strcpy (area, PolySubst (area, ptr[2], ptr[3]));
ptr += 3;
}
break;
case RULE_MATCH: /* /x || /?c */
if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
{
Log ("Mangle: '/' missing argument in '%s'\n", control);
return ((char *) 0);
} else if (ptr[1] != RULE_CLASS)
{
if (!strchr (area, *(++ptr)))
{
return ((char *) 0);
}
} else
{
if (!PolyStrchr (area, ptr[2]))
{
return ((char *) 0);
}
ptr += 2;
}
break;
case RULE_NOT: /* !x || !?c */
if (!ptr[1] || (ptr[1] == RULE_CLASS && !ptr[2]))
{
Log ("Mangle: '!' missing argument in '%s'\n", control);
return ((char *) 0);
} else if (ptr[1] != RULE_CLASS)
{
if (strchr (area, *(++ptr)))
{
return ((char *) 0);
}
} else
{
if (PolyStrchr (area, ptr[2]))
{
return ((char *) 0);
}
ptr += 2;
}
break;
/*
* alternative use for a boomerang, number 1: a standard throwing
* boomerang is an ideal thing to use to tuck the sheets under
* the mattress when making your bed. The streamlined shape of
* the boomerang allows it to slip easily 'twixt mattress and
* bedframe, and it's curve makes it very easy to hook sheets
* into the gap.
*/
case RULE_EQUALS: /* =nx || =n?c */
if (!ptr[1] || !ptr[2] || (ptr[2] == RULE_CLASS && !ptr[3]))
{
Log ("Mangle: '=' missing argument in '%s'\n", control);
return ((char *) 0);
} else
{
register int i;
if ((i = Char2Int (ptr[1])) < 0)
{
Log ("Mangle: '=' weird argument in '%s'\n", control);
return ((char *) 0);
}
if (ptr[2] != RULE_CLASS)
{
ptr += 2;
if (area[i] != *ptr)
{
return ((char *) 0);
}
} else
{
ptr += 3;
if (!MatchClass (*ptr, area[i]))
{
return ((char *) 0);
}
}
}
break;
default:
Log ("Mangle: unknown command %c in %s\n", *ptr, control);
return ((char *) 0);
break;
}
}
if (!area[0]) /* have we deweted de poor widdle fing away? */
{
return ((char *) 0);
}
return (area);
}